package ar.com.globallogic.promomr.api.controllers;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import ar.com.globallogic.promomr.api.converters.PublicationConverter;
import ar.com.globallogic.promomr.api.converters.PublicationFilterConverter;
import ar.com.globallogic.promomr.api.resources.PublicationFilterRequest;
import ar.com.globallogic.promomr.api.resources.PublicationRequest;
import ar.com.globallogic.promomr.api.resources.PublicationResponse;
import ar.com.globallogic.promomr.domain.Publication;
import ar.com.globallogic.promomr.domain.User;
import ar.com.globallogic.promomr.services.ContentService;
import ar.com.globallogic.promomr.services.PublicationService;
import ar.com.globallogic.promomr.services.SecurityService;

@Controller
@RequestMapping("/api/publications")
public class PublicationController {
	
	private PublicationService publicationService;
	private ContentService contentService;
	private SecurityService securityService;
	

	@Autowired
	public PublicationController(PublicationService publicationService, ContentService contentService, SecurityService securityService) {
		super();
		this.publicationService = publicationService;
		this.contentService = contentService;
		this.securityService = securityService;
	}
	
	@RequestMapping(value="{id}",method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody PublicationResponse getPublication(@PathVariable String id) {
		Publication publication = publicationService.findOne(id);
		return PublicationConverter.convert(publication);
	}
	
	@RequestMapping(method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody PublicationResponse getPublicationByContentId(@RequestParam(value="contentId") String contentId) {
		Publication publication = publicationService.findByContentId(contentId);
		return PublicationConverter.convert(publication);
	}

	@RequestMapping(value="publications",method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody void publish(@RequestBody PublicationRequest publicationRequest) {
		Publication publication = publicationService.findByContentId(publicationRequest.getContentId());
		addFilters(publicationRequest.getFilters(), publication);
		publicationService.publish(publication);
	}

	private void addFilters(List<PublicationFilterRequest> filters, Publication publication) {
		publication.removeFilters();
		for (PublicationFilterRequest filterRequest : filters) {
			publication.addFilter(PublicationFilterConverter.convert(filterRequest));
		}
	}
	
	@RequestMapping(value="automatic-publications",method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody void publishAtDate(@RequestBody PublicationRequest publicationRequest) {
		Publication publication = publicationService.findByContentId(publicationRequest.getContentId());
		addFilters(publicationRequest.getFilters(), publication);
		publicationService.publishAt(publication, publicationRequest.getPublicationDate());
	}
	
	@RequestMapping(value="cancellations",method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody void cancel(@RequestBody PublicationRequest publicationRequest) {
		Publication publication = publicationService.findByContentId(publicationRequest.getContentId());
		publication.removeFilters();
		publicationService.cancel(publication);
	}

	@RequestMapping(value="/contents",method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<PublicationResponse> getContentByProperties(
					@RequestParam(value="name", required=false) String name,
					@RequestParam(value="description", required=false) String description) {
		List<String> ids = contentService.findByProperties(name, description);
		User authenticatedUser = securityService.getAuthenticatedUser();		
		List<Publication> publications = publicationService.findPublicationsForContentIdsAndUserId(ids, authenticatedUser.getId());
		return PublicationConverter.convert(publications);
	}
	
	@RequestMapping(value="contents/videos",method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<PublicationResponse> getVideosByProperties(
			@RequestParam(value="name", required=false) String name,
			@RequestParam(value="description", required=false) String description,
			@RequestParam(value="format", required=false) String format,
			@RequestParam(value="quality", required=false) String quality,
			@RequestParam(value="durationgte", required=false) Long durationInSecondsGreaterThanEquals,
			@RequestParam(value="durationlte", required=false) Long durationInSecondsLessThanEquals) {
		List<String> ids = contentService.findVideosByProperties(name, description, format, quality, durationInSecondsGreaterThanEquals, durationInSecondsLessThanEquals);
		User authenticatedUser = securityService.getAuthenticatedUser();		
		List<Publication> publications = publicationService.findPublicationsForContentIdsAndUserId(ids, authenticatedUser.getId());
		return PublicationConverter.convert(publications);
	}
	
	@RequestMapping(value="contents/images",method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<PublicationResponse> getImagesByProperties(
			@RequestParam(value="name", required=false) String name,
			@RequestParam(value="description", required=false) String description,
			@RequestParam(value="labels", required=false) List<String> labels) {
		List<String> ids = contentService.findImagesByProperties(name, description, labels);
		User authenticatedUser = securityService.getAuthenticatedUser();
		List<Publication> publications = publicationService.findPublicationsForContentIdsAndUserId(ids, authenticatedUser.getId());
		return PublicationConverter.convert(publications);
	}
	
	@RequestMapping(value="contents/documents",method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<PublicationResponse> getDocumentsByProperties(
			@RequestParam(value="name", required=false) String name,
			@RequestParam(value="description", required=false) String description,
			@RequestParam(value="title", required=false) String title,
			@RequestParam(value="author", required=false) String author,
			@RequestParam(value="pagesgte", required=false) Long amountOfPagesGreaterThanEquals,
			@RequestParam(value="pageslte", required=false) Long amountOfPagesLessThanEquals) {
		List<String> ids = contentService.findDocumentsByProperties(name, description, title, author, amountOfPagesGreaterThanEquals, amountOfPagesLessThanEquals);
		User authenticatedUser = securityService.getAuthenticatedUser();
		List<Publication> publications = publicationService.findPublicationsForContentIdsAndUserId(ids, authenticatedUser.getId());
		return PublicationConverter.convert(publications);
	}
}
